package com.atguigu.crowd.util;


import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.comm.ResponseMessage;
import com.aliyun.oss.model.PutObjectResult;
import com.atguigu.crowd.constant.CrowdConstant;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

public class CrowdUtil {


 //   private static Logger logger = LoggerFactory.getLogger(CrowdUtil.class);

    /**
     * 专门负责上传文件到OSS服务器的工具方法
     * @param endpoint			OSS参数
     * @param accessKeyId		OSS参数
     * @param accessKeySecret	OSS参数
     * @param inputStream		要上传的文件的输入流
     * @param bucketName		OSS参数
     * @param bucketDomain		OSS参数
     * @param originalName		要上传的文件的原始文件名
     * @return	包含上传结果以及上传的文件在OSS上的访问路径
     */
    public static ResultEntity<String> uploadFileToOss(
            String endpoint,
            String accessKeyId,
            String accessKeySecret,
            InputStream inputStream,
            String bucketName,
            String bucketDomain,
            String originalName) {

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        // 生成上传文件的目录
        String folderName = new SimpleDateFormat("yyyyMMdd").format(new Date());

        // 生成上传文件在OSS服务器上保存时的文件名
        // 原始文件名：beautfulgirl.jpg
        // 生成文件名：wer234234efwer235346457dfswet346235.jpg
        // 使用UUID生成文件主体名称
        String fileMainName = UUID.randomUUID().toString().replace("-", "");

        // 从原始文件名中获取文件扩展名
        String extensionName = originalName.substring(originalName.lastIndexOf("."));

        // 使用目录、文件主体名称、文件扩展名称拼接得到对象名称
        String objectName = folderName + "/" + fileMainName + extensionName;

        try {
            // 调用OSS客户端对象的方法上传文件并获取响应结果数据
            PutObjectResult putObjectResult = ossClient.putObject(bucketName, objectName, inputStream);

            // 从响应结果中获取具体响应消息
            ResponseMessage responseMessage = putObjectResult.getResponse();

            // 根据响应状态码判断请求是否成功
            if(responseMessage == null) {

                // 拼接访问刚刚上传的文件的路径
                String ossFileAccessPath = bucketDomain + "/" + objectName;

                // 当前方法返回成功
                return ResultEntity.successWithData(ossFileAccessPath);
            } else {
                // 获取响应状态码
                int statusCode = responseMessage.getStatusCode();

                // 如果请求没有成功，获取错误消息
                String errorMessage = responseMessage.getErrorResponseAsString();

                // 当前方法返回失败
                return ResultEntity.failed("当前响应状态码="+statusCode+" 错误消息="+errorMessage);
            }
        } catch (Exception e) {
            e.printStackTrace();

            // 当前方法返回失败
            return ResultEntity.failed(e.getMessage());
        } finally {

            if(ossClient != null) {

                // 关闭OSSClient。
                ossClient.shutdown();
            }
        }

    }
//    public static void main(String[] args) throws IOException {
        //通过getResource拿到target/classes/下的文件 然后分割 这样做的前提是图片被编译进文件夹中
        //每次添加完图片都要rebuild下images文件夹 麻烦

        //从src下获取文件路径 不是target/classes

//        String filepath = "common-uitls/src/main/resources/images/pig.jpg";
//        File temp = new File(filepath);
//        System.out.println(temp.getAbsolutePath());

        //使用File对象的getAbsolutePath()就不需要再切割
//       File file = new File(CrowdUtil.class.getClassLoader().getResource("images/333.jpg").getFile());
//        System.out.println(file.getAbsolutePath());
//        URL resource = CrowdUtil.class.getResource("/images/333.jpg");
//        System.out.println(resource);
//        String Sre = String.valueOf(resource);
//        String newS = Sre.substring(6);
//        System.out.println(newS);
    //    F:\java_p\crowd\common-uitls\src\main\resources\images\pig.jpg
      //  FileInputStream inputStrea1=new FileInputStream("F:\\java_p\\crowd\\common-uitls\\src\\main\\resources\\images\\pig.jpg");

//       FileInputStream inputStream = new FileInputStream(temp.getAbsolutePath());
//        ResultEntity<String> resultEntity = uploadFileToOss("http://oss-cn-beijing.aliyuncs.com",
//                "LTAI4GDfkiDf3LM46HZ2GUZ4",
//                "SLbTPb7PTBEzpstH5xYskh0tAvBM5J",
//                inputStream,
//                "atguigu-1015-crowd",
//                "http://atguigu-1015-crowd.oss-cn-beijing.aliyuncs.com",
//                "333.jpg");
//        System.out.println(resultEntity);
//    }

    //向手机发送验证码短信
    /*
     * 给远程第三方短信接口发送请求把验证码发送到用户手机上
     * 成功 返回验证码
     * 失败 返回失败信息
     * */
    public static ResultEntity<String> sendCodeByShortMessage(String host, String path, String phone, String appcode, String templateId) {
        // 生成验证码
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            int random = (int) (Math.random() * 10);
            builder.append(random);
        }
        String code = builder.toString();
//        String urlSend = host + path + "?receive=" + phone + "&tag=" + code + "&templateId=" + templateId; // 【5】拼接请求链接

        Map<String, String> headers = new HashMap<String, String>();

        headers.put("Authorization", "APPCODE " + appcode);
        Map<String, String> querys = new HashMap<String, String>();
        querys.put("receive", phone);
        querys.put("tag", code);
        querys.put("templateId", "M09DD535F4");
        Map<String, String> bodys = new HashMap<String, String>();


        try {

            HttpResponse response = HttpUtils.doPost(host, path, "POST", headers, querys, bodys);
            System.out.println(response.toString());
            //获取response的body
            System.out.println(EntityUtils.toString(response.getEntity()));


            int httpCode = response.getStatusLine().getStatusCode();
            if (httpCode == 200) {
                return ResultEntity.successWithData(code);
            } else if(httpCode == 400){
                return ResultEntity.failed("错误");
            }
            } catch(Exception e){
                e.printStackTrace();
            }
            return ResultEntity.successWithData(code);
//        String urlSend = host + path + "?sign=" + sign + "&skin=" + skin + "&param=" + code + "&phone=" + phone; // 【5】拼接请求链接
//        try {
//            URL url = new URL(urlSend);
//            HttpURLConnection httpURLCon = (HttpURLConnection) url.openConnection();
//            httpURLCon.setRequestProperty("Authorization", "APPCODE " + appcode);// 格式Authorization:APPCODE
//            // (中间是英文空格)
//            int httpCode = httpURLCon.getResponseCode();
//            if (httpCode == 200) {
//                String json = read(httpURLCon.getInputStream());
//               // logger.debug("正常请求计费(其他均不计费)");
//              //  System.out.println("正常请求计费(其他均不计费)");
//              //  System.out.println("获取返回的json:");
//             //   System.out.print(json);
//                return ResultEntity.successWithData(code);
//            } else {
//                Map<String, List<String>> map = httpURLCon.getHeaderFields();
//                String error = map.get("X-Ca-Error-Message").get(0);
//                if (httpCode == 400 && error.equals("Invalid AppCode `not exists`")) {
//                  // logger.debug("AppCode错误 ");
//                 //   System.out.println("AppCode错误 ");
//                } else if (httpCode == 400 && error.equals("Invalid Url")) {
//                  //  logger.debug("请求的 Method、Path 或者环境错误 ");
//                   // System.out.println("请求的 Method、Path 或者环境错误");
//                } else if (httpCode == 400 && error.equals("Invalid Param Location")) {
//                //    logger.debug("参数错误 ");
//                    System.out.println("参数错误");
//                } else if (httpCode == 403 && error.equals("Unauthorized")) {
//                    //logger.debug("服务未被授权（或URL和Path不正确） ");
//                    System.out.println("服务未被授权（或URL和Path不正确）");
//                } else if (httpCode == 403 && error.equals("Quota Exhausted")) {
////                    logger.debug("套餐包次数用完 ");
////                    System.out.println("套餐包次数用完 ");
//                } else {
////                    logger.debug("参数名错误 或 其他错误 ");
////                    System.out.println("参数名错误 或 其他错误");
////                    System.out.println(error);
//                }
//                return ResultEntity.failed(error);
//            }
//
//        }  catch (Exception e) {
//            // 打开注释查看详细报错异常信息
//            e.printStackTrace();
//            return ResultEntity.failed(e.getMessage());
//        }
            //  return ResultEntity.successWithoutData();
        }





    /*
     * 短信验证码 读取返回结果
     */
    private static String read(InputStream is) throws IOException {
        StringBuffer sb = new StringBuffer();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = null;
        while ((line = br.readLine()) != null) {
            line = new String(line.getBytes(), "utf-8");
            sb.append(line);
        }
        br.close();
        return sb.toString();
    }





    /**
     * 判断当前请求是否为Ajax请求  用于之后进行异常处理
     * AJAX请求不返回页面
     * 将异常消息封装到返回结果对象ResultEntity
     * 并转换成JSON字符串响应给浏览器
     *
     * 普通请求返回异常页面
     *
     * 在自定义异常处理器中进行判断
     *
     * @param request 请求对象
     * @return
     * 		true：当前请求是Ajax请求
     * 		false：当前请求不是Ajax请求
     */
    public static boolean judgeRequestType(HttpServletRequest request){
        //需要看请求头
        // 1.获取请求消息头
        String accept = request.getHeader("Accept");
        String xRequestHeader = request.getHeader("X-Requested-With");
        return ((accept != null && accept.contains("application/json"))||
                (xRequestHeader !=null && xRequestHeader.equals("XMLHttpRequest"))
        );
    }


    /**
     * 对明文字符串进行MD5加密
     * @param source 传入的明文字符串
     * @return 加密结果
     */
    public static String md5(String source){
        //1.判断source是否有效
        if(source == null || source.length() == 0){

            //2.不是有效字符串 抛出异常
            throw new RuntimeException(CrowdConstant.MESSAGE_STRING_INVALIDATE);

        }


        try {
            //3.获取MessageDigest对象
            String algorithm="md5";

            MessageDigest messageDigest = MessageDigest.getInstance(algorithm);

            //4.获取明文字符串对应的字节数组
            byte[] input = source.getBytes();

            //5.执行加密
            byte[] output = messageDigest.digest(input);

            //6.创建BigInteger对象
            int signum=1;
            BigInteger bigInteger = new BigInteger(signum, output);

            //7.按照16进制将bigInteger转换为字符串
            int radix=16;
            String encoded = bigInteger.toString(radix).toUpperCase();

            return encoded;

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }



}
